﻿using LiveCharts.Wpf;
using LiveCharts;
using Sunny.UI;
using System.Net.Sockets;
using System.Net;
using File = System.IO.File;
using Excel = Microsoft.Office.Interop.Excel;
using MessageBox = System.Windows.Forms.MessageBox;
using System.Configuration;
using System.Net.Mail;

using TencentCloud.Common;
using TencentCloud.Common.Profile;
using TencentCloud.Sms.V20210111;
using TencentCloud.Sms.V20210111.Models;
using System.Threading;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

enum SENSOR_TYPE : int
{
    NORMAL_SENSOR = 0, STRAIN_SENSOR, TEMPER_SENSOR, DISPLACE_SENSOR
};

namespace FZRD
{
    public partial class Page1 : UIPage
    {
        //监听线程
        //[DisallowNull]
        public static Thread receiveThread1;

        bool debug = true;
        //X轴值数量初始值
        private long xCount = 60;
        //X轴值最大计数值
        private long xTimes = 60;
        //显示时长
        private long showTimes = 60;//(秒)
        //当前时间
        private long lastTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        //采样频率
        private long frequency = 1;
        //采集间隔
        private long intervalTime = 1000;//(毫秒)
        //通道初始值
        private int channelIndex = 0;
        //通道初始值
        private int rasterIndex = 0;
        //光栅总数
        private int rasterCount = 16;
        //通道总数
        private int channelCount = 16;
        private Random R { get; set; }//为了给Y值提供随机值
        //定时刷新曲线
        private System.Windows.Forms.Timer timerChart;

        //普通传感器 0
        //应变传感器 1
        //温度传感器 2
        //震动传感器 3
        //位移传感器 4
        private int sensorType = 0;

        private bool isSaveWaveLength = false;

        private bool isSaveToMysqlDB = false;

        private string waveFilePath = "D:\\聚芯光纤\\";

        private string waveFileName = "波长数据";

        private string waveFileNameDate = "";

        //[DisallowNull]
        private Excel.Application excelApp;

        //[DisallowNull]
        private Excel._Workbook workbook;

        private bool isWaveCollectTimes = false;

        private int waveCollectTimes = 0;

        private List<ColumnData> dataList = new List<ColumnData>();

        //轴力超过阈值次数
        private int axialAlarmRepeatTimes = 0;

        public Page1()
        {
            InitializeComponent();
            InitChartConfig();

            #region  多Y轴曲线
            //将自定义类型MeasureModel映射到曲线坐标点
            var mapper = LiveCharts.Configurations.Mappers.Xy<DataPoint>()
              .X(model => model.Times)    //使用 Time.作为X轴的标签
              .Y(model => model.Value);  //使用Value 作为Y轴的值

            //全局保存映射器
            Charting.For<DataPoint>(mapper);
            #endregion

            this.cbWaveChannelSellect.SelectedIndex = Convert.ToInt32(ConfigurationManager.AppSettings["cbWaveChannelSellect"]);
            this.cbWaveSensorSellect.SelectedIndex = Convert.ToInt32(ConfigurationManager.AppSettings["cbWaveSensorSellect"]);
            this.cbWaveSensorType.SelectedIndex = Convert.ToInt32(ConfigurationManager.AppSettings["cbWaveSensorType"]);
            this.tbWaveFrequency.Text = ConfigurationManager.AppSettings["tbWaveFrequency"];
            this.cbWaveCollectTimes.Checked = Convert.ToBoolean(ConfigurationManager.AppSettings["cbWaveCollectTimes"]);
            this.tbWaveCollectTimes.Text = ConfigurationManager.AppSettings["tbWaveCollectTimes"];
            this.cbWaveSavePath.Checked = Convert.ToBoolean(ConfigurationManager.AppSettings["cbWaveSavePath"]);
            
            this.waveFilePath = ConfigurationManager.AppSettings["tbWaveFilePath"]; 
            
            this.waveFileName = ConfigurationManager.AppSettings["waveFileName"];

            this.tbWaveFilePath.Text = this.waveFilePath;

            this.isSaveToMysqlDB = Convert.ToBoolean(ConfigurationManager.AppSettings["isSaveToMysqlDB"]);

            //CreateExcelDataFile();

            if (this.tbWaveFrequency.Text.Length > 0)
            {
                long _frequency = Convert.ToInt64(this.tbWaveFrequency.Text);
                //转换成长整型
                if (this.frequency != _frequency)
                {
                    this.frequency = _frequency;
                    this.intervalTime = 1000 / this.frequency;
                    this.xCount = this.showTimes * this.frequency;
                }
            }

            for (int i = 0; i < channelCount; i++)
            {
                ColumnData columnData = new ColumnData();
                dataList.Add(columnData);
            }
            uiDataGridView1.DataSource = dataList;

            uiDataGridView1.ReadOnly = true;

            this.debug = this.cbSimulationTest.Checked;
            R = new Random();

            //定时器刷新
            this.timerChart = new System.Windows.Forms.Timer()
            {
                Interval = (int)(this.intervalTime)
            };
            this.timerChart.Tick += TimerChart_Tick;
            this.timerChart.Start();

            //开启接收消息线程
            //receiveThread1 = new Thread(ReciveMessage);
            //receiveThread1.Start();
        }

        //窗口关闭事件委托，在窗口关闭事件前处理
        private void Page1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (receiveThread1 != null)
            {
                receiveThread1.Interrupt();
            }
            if (this.isSaveWaveLength)
            {
                if (this.excelApp != null)
                {
                    this.excelApp.DisplayAlerts = false;
                    if (this.workbook != null)
                    {
                        this.workbook.Close(false);
                        this.workbook = null;
                    }
                    this.excelApp.Quit();
                    this.excelApp = null;
                }
            }
        }

        private void TimerChart_Tick(object sender, EventArgs e)
        {
            if (this.debug)
            {
                LineSeriesRefresh();
            }
        }

        /// <summary>
        /// 连续折现图的方法
        /// </summary>
        private void LineSeriesRefresh()
        {
            long nowTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            if ((nowTime - this.lastTime) < this.intervalTime)
            {
                return;
            }
            this.xTimes++;

            string[] values = new string[rasterCount + 2];

            for (int channelID = 0; channelID < this.channelCount; channelID++)
            {
                if (channelID == this.channelIndex)
                {
                    values[0] = 1 + channelID + "";
                    values[1] = 2 + "";
                    //更新纵坐标数据
                    double waveLength1 = Math.Round(R.NextDouble() + Page3.getS1A1(), 4);
                    double waveLength2 = Math.Round(R.NextDouble() + Page3.getS1A2(), 4);
                    double stressValue1 = CalculateStress(waveLength1, waveLength2, Page3.getS1A1(), Page3.getS1A2(), Page3.getS1K1(), Page3.getS1K2(), Page3.getS1K3());

                    values[2] = waveLength1 + "";
                    values[3] = waveLength2 + "";
                    values[4] = stressValue1 + "";

                    double waveLength3 = Math.Round(R.NextDouble() + Page3.getS2A1(), 4);
                    double waveLength4 = Math.Round(R.NextDouble() + Page3.getS2A2(), 4);
                    double stressValue2 = CalculateStress(waveLength3, waveLength4, Page3.getS2A1(), Page3.getS2A2(), Page3.getS2K1(), Page3.getS2K2(), Page3.getS2K3());
                    
                    values[5] = waveLength3 + "";
                    values[6] = waveLength4 + "";
                    values[7] = stressValue2 + "";

                    double axialForce = Math.Round(Math.Abs(((stressValue1 + stressValue2) * Page3.getEM1() * Page3.getPE()) / (Page3.getPI() * 32 * 32)) + Page3.getAF1(), 4);
                    if (axialForce > Page3.getAxialForceExceeds())
                    {
                        this.axialAlarmRepeatTimes++;
                        if (Page3.getIsAlarmNotify())
                        {
                            if (this.axialAlarmRepeatTimes > Page3.getRepeatTimes())
                            {
                                if (Page3.getIsAlarmEmail())
                                {
                                    SendEmail("smtp.qq.com", 587, "24139297@qq.com", "rvsdsfqwexwrbgba", Page3.getAlarmEmail(), "告警通知", "通道：" + channelID + " 轴力值：" + axialForce + " 连续 " + this.axialAlarmRepeatTimes + " 次" + "超过警告阈值：" + Page3.getAxialForceExceeds() + "，请注意！");
                                }
                                if (Page3.getIsAlarmPhone())
                                {
                                    int roundedValue = Convert.ToInt32(axialForce);
                                    string[] templateParamSet = [channelID + "", roundedValue + "", this.axialAlarmRepeatTimes + ""];
                                    SendSms(Page3.getAlarmPhone(), templateParamSet);
                                }
                                this.axialAlarmRepeatTimes = 0;
                            }
                        }
                    }
                    values[8] = axialForce + "";

                    ChartLineRefresh(0, axialForce);
                    //保存到Excel文件
                    //SaveDataToExcel(values, sensorType);
                    //SaveDataToMysql(values, nowTime, sensorType);
                    ShowDataView(values, channelID);
                }
            }
        }


        private void ChartLineRefresh(int index, double walue)
        {
            // 假设你在非UI线程上
            if (OscChart.InvokeRequired)
            {
                OscChart.Invoke(new System.Action(() =>
                {
                    //添加y值，pointValue1为波长1数据
                    var pointValue = new DataPoint(this.xTimes, walue);
                    OscChart.Series[index].Values.Add(pointValue);
                    int _count = OscChart.Series[index].Values.Count;
                    if (_count > this.xCount)
                    {
                        //只关心前面30个数据
                        OscChart.Series[index].Values.RemoveAt(0);
                    }
                    //在这里进行UI相关的操作，例如修改OscChart的属性等
                    OscChart.AxisX[index].MaxValue = this.xTimes;
                    OscChart.AxisX[index].MinValue = this.xTimes - this.xCount;
                    OscChart.Refresh();
                }));
            }
            else
            {
                OscChart.Series[index].Values.Add(new DataPoint(this.xTimes, walue));
                int _count = OscChart.Series[index].Values.Count;
                if (_count > this.xCount)
                {
                    //只关心前面30个数据
                    OscChart.Series[index].Values.RemoveAt(0);
                }
                // 直接进行操作，因为当前线程就是UI线程
                OscChart.AxisX[index].MaxValue = this.xTimes;
                OscChart.AxisX[index].MinValue = this.xTimes - this.xCount;
                OscChart.Refresh();

            }
        }

        private void InitChartConfig()
        {
            string title = "值";
            if (OscChart.InvokeRequired)
            {
                OscChart.Invoke(new System.Action(() =>
                {
                    OscChart.Series.Add(new LineSeries
                    {
                        Title = title,
                        PointGeometry = DefaultGeometries.Circle,
                        PointGeometrySize = 15,
                        StrokeThickness = 4,
                        LineSmoothness = 0,
                        PointForeground = System.Windows.Media.Brushes.Blue,
                        Values = InitChartValuesData(),
                        ScalesYAt = 0
                    });
                    OscChart.AxisX.Add(new LiveCharts.Wpf.Axis
                    {
                        //Title = "时间",
                        FontSize = 12,
                        DisableAnimations = true,
                        Foreground = System.Windows.Media.Brushes.Black,
                        LabelFormatter = value => value.ToString(),
                        //LabelFormatter = value => new System.DateTime(System.DateTime.Now.Ticks - (long)(this.xNumber - (long)value) * this.intervalTime * 10000).ToString("mm:ss"),
                        Separator = new Separator
                        {
                            Step = 1,
                            IsEnabled = true
                        },
                        MaxValue = this.xTimes,
                        MinValue = this.xTimes - this.xCount
                    });

                    OscChart.AxisY.Add(new LiveCharts.Wpf.Axis
                    {
                        Title = title,
                        FontSize = 12,
                        Foreground = System.Windows.Media.Brushes.DodgerBlue,
                        Position = AxisPosition.LeftBottom
                    });
                }));
            }
            else
            {
                OscChart.Series.Add(new LineSeries
                {
                    Title = title,
                    PointGeometry = DefaultGeometries.Circle,
                    PointGeometrySize = 15,
                    StrokeThickness = 4,
                    LineSmoothness = 0,
                    PointForeground = System.Windows.Media.Brushes.Blue,
                    Values = InitChartValuesData(),
                    ScalesYAt = 0
                });
                OscChart.AxisX.Add(new LiveCharts.Wpf.Axis
                {
                    //Title = "时间",
                    FontSize = 12,
                    DisableAnimations = true,
                    Foreground = System.Windows.Media.Brushes.Black,
                    LabelFormatter = value => value.ToString(),
                    //LabelFormatter = value => new System.DateTime(System.DateTime.Now.Ticks - (long)(this.xNumber - (long)value) * this.intervalTime * 10000).ToString("mm:ss"),
                    Separator = new Separator
                    {
                        Step = 1,
                        IsEnabled = true
                    },
                    MaxValue = this.xTimes,
                    MinValue = this.xTimes - this.xCount
                });
                OscChart.AxisY.Add(new LiveCharts.Wpf.Axis
                {
                    Title = title,
                    FontSize = 12,
                    Foreground = System.Windows.Media.Brushes.DodgerBlue,
                    Position = AxisPosition.LeftBottom
                });
            }
        }

        private void InitChartConfig(int channelID, int rasterID, int yIndex)
        {
            string title = "通道-" + (channelID + 1) + "-传感器-" + (rasterID + 1);
            //string wave = "波长";
            if (OscChart.InvokeRequired)
            {
                OscChart.Invoke(new System.Action(() =>
                {
                    OscChart.Series.Add(new LineSeries
                    {
                        Title = title,
                        PointGeometry = DefaultGeometries.Circle,
                        PointGeometrySize = 15,
                        StrokeThickness = 4,
                        LineSmoothness = 0,
                        PointForeground = System.Windows.Media.Brushes.Blue,
                        Values = InitChartValuesEmptyData(),
                        ScalesYAt = yIndex
                    });
                    OscChart.AxisX.Add(new LiveCharts.Wpf.Axis
                    {
                        //Title = "时间",
                        FontSize = 12,
                        DisableAnimations = true,
                        Foreground = System.Windows.Media.Brushes.Black,
                        LabelFormatter = value => value.ToString(),
                        //LabelFormatter = value => new System.DateTime(System.DateTime.Now.Ticks - (long)(this.xNumber - (long)value) * this.intervalTime * 10000).ToString("mm:ss"),
                        Separator = new Separator
                        {
                            Step = 1,
                            IsEnabled = true
                        },
                        MaxValue = this.xTimes,
                        MinValue = this.xTimes - this.xCount
                    });

                    OscChart.AxisY.Add(new LiveCharts.Wpf.Axis
                    {
                        Title = "值",
                        FontSize = 12,
                        Foreground = System.Windows.Media.Brushes.DodgerBlue,
                        Position = AxisPosition.LeftBottom
                    });
                }));
            }
            else
            {
                OscChart.Series.Add(new LineSeries
                {
                    Title = title,
                    PointGeometry = DefaultGeometries.Circle,
                    PointGeometrySize = 15,
                    StrokeThickness = 4,
                    LineSmoothness = 0,
                    PointForeground = System.Windows.Media.Brushes.Blue,
                    Values = InitChartValuesEmptyData(),
                    ScalesYAt = yIndex
                });
                OscChart.AxisX.Add(new LiveCharts.Wpf.Axis
                {
                    //Title = "时间",
                    FontSize = 12,
                    DisableAnimations = true,
                    Foreground = System.Windows.Media.Brushes.Black,
                    LabelFormatter = value => value.ToString(),
                    //LabelFormatter = value => new System.DateTime(System.DateTime.Now.Ticks - (long)(this.xNumber - (long)value) * this.intervalTime * 10000).ToString("mm:ss"),
                    Separator = new Separator
                    {
                        Step = 1,
                        IsEnabled = true
                    },
                    MaxValue = this.xTimes,
                    MinValue = this.xTimes - this.xCount
                });

                OscChart.AxisY.Add(new LiveCharts.Wpf.Axis
                {
                    Title = "值",
                    FontSize = 12,
                    Foreground = System.Windows.Media.Brushes.DodgerBlue,
                    Position = AxisPosition.LeftBottom
                });
            }
        }

        private ChartValues<DataPoint> InitChartValuesData()
        {
            ChartValues<DataPoint> chartValues = new ChartValues<DataPoint>();
            for (long i = 1; i <= this.xCount; i++)
            {
                chartValues.Add(new DataPoint(i, 1550.00001D));
            }
            this.xTimes = this.xCount;
            return chartValues;
        }

        private static ChartValues<DataPoint> InitChartValuesEmptyData()
        {
            ChartValues<DataPoint> chartValues = new ChartValues<DataPoint>();
            return chartValues;
        }


        // 接收发送给本机IP对应端口号的数据报
        private void ReciveMessage()
        {
            try
            {
                while (MainForm.getOpenServerPort())
                {
                    //用来保存发送方的IP和端口号
                    EndPoint point = new IPEndPoint(IPAddress.Any, 0);
                    //消息缓存区申请
                    byte[] buffer = new byte[512];
                    Socket serverSocket = MainForm.getServerSocket();
                    if (serverSocket != null){
                        //接收数据报
                        int length = serverSocket.ReceiveFrom(buffer, ref point);
                        byte[] revBuf = new byte[length];
                        Buffer.BlockCopy(buffer, 0, revBuf, 0, length);
                        //显示在波形图里
                        this.ReciveWaveDataOPM(revBuf);
                    }
                }
            }
            catch (SocketException e)
            {
                //MessageBox.Show("接收发送给本机IP对应端口号的数据报错！" + e.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                //if (serverSocket != null)
                //{
                //    if (serverSocket.Connected)
                //    {
                //        serverSocket.Disconnect(false);
                //    }
                //    serverSocket.Close();
                //    serverSocket.Dispose();
                //}
            }
        }
        //CFBG光栅解调仪设备通信协议解析
        private void ReciveWaveDataCFBG(byte[] revData)
        {

            if (revData.Length != 494)
            {
                return;
            }

            long nowTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            if ((nowTime - this.lastTime) < this.intervalTime)
            {
                return;
            }
            this.lastTime = nowTime;
            this.xTimes++;
            byte cmd = revData[0];
            byte code = revData[1];
            byte[] tempArray = new byte[4];
            Array.Copy(revData, 2, tempArray, 0, 4);
            uint length = BitConverter.ToUInt32(tempArray, 0);
            for (int channelId = 0; channelId < channelCount; channelId++)
            {
                byte[] tempChannelArray = new byte[122];
                Array.Copy(revData, 122 * channelId + 6, tempChannelArray, 0, 122);
                byte[] tempNodeArray = new byte[4];
                Array.Copy(tempChannelArray, 0, tempNodeArray, 0, 4);
                uint yValue = (UInt32)((tempNodeArray[0] << 24) | (tempNodeArray[1] << 16) | (tempNodeArray[2] << 8) | tempNodeArray[3]);
                if (yValue > 0)
                {
                    var waveLength = (double)DivideAndRound(2997924608L, yValue, 5);
                    if (channelId == channelIndex)
                    {
                        ChartLineRefresh(0, waveLength);
                    }
                }
            }
        }

        //OPM-T1622F 光栅解调仪设备通信协议解析
        private void ReciveWaveDataOPM(byte[] revData)
        {
            long nowTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            if ((nowTime - this.lastTime) < this.intervalTime)
            {
                return;
            }
            this.lastTime = nowTime;

            this.xTimes++;

            if (this.xTimes >= long.MaxValue - 1000)
            {
                this.xTimes = this.xCount;
            }
            if ((this.isWaveCollectTimes) && (this.xTimes > this.waveCollectTimes))
            {
                //UI显示
                this.btnCollectWave.Text = "开始采集";
                this.btnCollectWave.Enabled = true;
                this.tbWaveFrequency.Enabled = true;
                this.tbWaveCollectTimes.Enabled = true;
                this.cbWaveCollectTimes.Enabled = true;
                this.tbWaveFilePath.Enabled = true;
                this.ibOpenFilePath.Enabled = true;
                this.cbWaveSavePath.Enabled = true;

                Socket serverSocket = MainForm.getServerSocket();
                if (serverSocket == null){
                    return;
                }
                try
                {
                    EndPoint endPoint = MainForm.getEndPoint();
                    byte[] bmsg = [0x01, 0x0A, 0x00];

                    //发送数据包
                    serverSocket.SendTo(bmsg, endPoint);

                    //先关闭线程，再关闭服务器
                    //if (receiveThread1 != null){
                    //    receiveThread1.Interrupt();
                    //}
                }
                catch (SocketException es)
                {
                    MessageBox.Show("发送数据报时出现异常：" + es.ErrorCode + "！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {

                }
                return;
            }

            byte head = revData[0];
            byte cmd = revData[1];

            if (cmd == 0x02)
            {

            }
            else if (cmd == 0x04)
            {

            }
            else if (cmd == 0x06)
            {

            }
            else if (cmd == 0x07)
            {

            }
            else if (cmd == 0x08)
            {

            }
            else if (cmd == 0x0A)
            {

            }
            else if (cmd == 0x0C)
            {
                int index = 2;
                for (int channelId = 0; channelId < channelCount; channelId++)
                {
                    index ++;
                    byte rasterCnt = revData[index];
                    if (sensorType == 1)//应变传感器
                    {
                        if ((rasterCnt >= 4) && (rasterCnt % 4 == 0) && (rasterCnt < rasterCount))
                        {
                            string[] values = new string[34];
                            values[0] = channelId + 1 + "";
                            values[1] = rasterCnt / 2 + "";

                            string[] columns = new string[18];
                            columns[0] = channelId + 1 + "";
                            columns[1] = rasterCnt + "";

                            byte[] tempArray = new byte[2 * rasterCnt];
                            Array.Copy(revData, index + 1, tempArray, 0, 2 * rasterCnt);

                            for (int rasterID = 0; rasterID < rasterCnt; rasterID++)
                            {
                                byte[] tempArray1 = new byte[2];
                                Array.Copy(tempArray, 2 * rasterID, tempArray1, 0, 2);
                                uint valueL1 = tempArray1[0];
                                uint valueH1 = tempArray1[1];
                                double waveLength1 = (double)DivideAndRound((valueL1 + valueH1 * 256), 1000, 5) + 1520;

                                byte[] tempArray2 = new byte[2];
                                Array.Copy(tempArray, 2 * (rasterID + 1), tempArray2, 0, 2);
                                uint valueL2 = tempArray2[0];
                                uint valueH2 = tempArray2[1];
                                double waveLength2 = (double)DivideAndRound((valueL2 + valueH2 * 256), 1000, 5) + 1520;

                                double stressValue1 = CalculateStress(waveLength1, waveLength2, Page3.getS1A2(), Page3.getS1A2(), Page3.getS1K1(), Page3.getS1K2(), Page3.getS1K3());

                                values[rasterID + 2] = waveLength1 + "";
                                values[rasterID + 3] = waveLength2 + "";
                                values[rasterID + 4] = stressValue1 + "";

                                columns[rasterID + 2] = waveLength1 + "";
                                columns[rasterID + 3] = waveLength2 + "";


                                byte[] tempArray3 = new byte[2];
                                Array.Copy(tempArray, 2 * (rasterID + 2), tempArray3, 0, 2);
                                uint valueL3 = tempArray3[0];
                                uint valueH3 = tempArray3[1];
                                double waveLength3 = (double)DivideAndRound((valueL3 + valueH3 * 256), 1000, 5) + 1520;

                                byte[] tempArray4 = new byte[2];
                                Array.Copy(tempArray, 2 * (rasterID + 3), tempArray4, 0, 2);
                                uint valueL4 = tempArray4[0];
                                uint valueH4 = tempArray4[1];
                                double waveLength4 = (double)DivideAndRound((valueL4 + valueH4 * 256), 1000, 5) + 1520;

                                double stressValue2 = CalculateStress(waveLength3, waveLength4, Page3.getS2A1(), Page3.getS2A2(), Page3.getS2K1(), Page3.getS2K2(), Page3.getS2K3());

                                //ε＝[（A1’－A1）- (A2’－A2)/ K2*K3] /K1
                                double axialForce = Math.Round(Math.Abs(((stressValue1 + stressValue2) * Page3.getEM1() * Page3.getPE()) / (Page3.getPI() * 32 * 32)) + Page3.getAF1(), 4);

                                values[rasterID + 5] = waveLength3 + "";
                                values[rasterID + 6] = waveLength4 + "";
                                values[rasterID + 7] = stressValue2 + "";
                                values[rasterID + 8] = axialForce + "";

                                columns[rasterID + 4] = waveLength3 + "";
                                columns[rasterID + 5] = waveLength4 + "";

                                rasterID = rasterID + 4;

                                if (axialForce > Page3.getAxialForceExceeds())
                                {
                                    this.axialAlarmRepeatTimes++;
                                    if (Page3.getIsAlarmNotify())
                                    {
                                        if (this.axialAlarmRepeatTimes > Page3.getRepeatTimes())
                                        {
                                            if (Page3.getIsAlarmEmail())
                                            {
                                                SendEmail("smtp.qq.com", 587, "24139297@qq.com", "rvsdsfqwexwrbgba", Page3.getAlarmEmail(), "告警通知", "通道：" + channelId + " 轴力值：" + axialForce + " 连续 " + this.axialAlarmRepeatTimes + " 次" + "超过警告阈值：" + Page3.getAxialForceExceeds() + "，请注意！");
                                            }
                                            if (Page3.getIsAlarmPhone())
                                            {
                                                int roundedValue = Convert.ToInt32(axialForce);
                                                string[] templateParamSet = [channelId + "", roundedValue + "", this.axialAlarmRepeatTimes + ""];
                                                SendSms(Page3.getAlarmPhone(), templateParamSet);
                                            }
                                        }
                                    }
                                }

                                if (channelId == this.channelIndex)
                                {
                                    ChartLineRefresh(0, axialForce);
                                }
                            }
                            //保存到Excel文件
                            SaveDataToExcel(values, sensorType);
                            SaveDataToMysql(values, nowTime, sensorType);
                            ShowDataView(columns, channelId);
                        }
                        else if ((rasterCnt >= 2) && (rasterCnt % 4 > 0) && (rasterCnt % 2 == 0) && (rasterCnt < rasterCount))
                        {
                            string[] values = new string[34];
                            values[0] = channelId + 1 + "";
                            values[1] = rasterCnt / 2 + "";

                            string[] columns = new string[18];
                            columns[0] = channelId + 1 + "";
                            columns[1] = rasterCnt + "";

                            byte[] tempArray = new byte[2 * rasterCnt];
                            Array.Copy(revData, index + 1, tempArray, 0, 2 * rasterCnt);

                            for (int rasterID = 0; rasterID < rasterCnt; rasterID++)
                            {
                                byte[] tempArray1 = new byte[2];
                                Array.Copy(tempArray, 2 * rasterID, tempArray1, 0, 2);
                                uint valueL1 = tempArray1[0];
                                uint valueH1 = tempArray1[1];
                                double waveLength1 = (double)DivideAndRound((valueL1 + valueH1 * 256), 1000, 5) + 1520;

                                byte[] tempArray2 = new byte[2];
                                Array.Copy(tempArray, 2 * (rasterID + 1), tempArray2, 0, 2);
                                uint valueL2 = tempArray2[0];
                                uint valueH2 = tempArray2[1];
                                double waveLength2 = (double)DivideAndRound((valueL2 + valueH2 * 256), 1000, 5) + 1520;

                                double stressValue1 = CalculateStress(waveLength1, waveLength2, Page3.getS1A2(), Page3.getS1A2(), Page3.getS1K1(), Page3.getS1K2(), Page3.getS1K3());

                                values[rasterID + 2] = waveLength1 + "";
                                values[rasterID + 3] = waveLength2 + "";
                                values[rasterID + 4] = stressValue1 + "";

                                //
                                double axialForce = Math.Round((Math.Abs(stressValue1) * Page3.getEM2()) * 0.00307 + Page3.getAF2(), 4);

                                values[rasterID + 5] = axialForce + "";

                                columns[rasterID + 2] = waveLength1 + "";
                                columns[rasterID + 3] = waveLength2 + "";

                                rasterID = rasterID + 2;

                                if (axialForce > Page3.getAxialForceExceeds())
                                {
                                    this.axialAlarmRepeatTimes++;
                                    if (Page3.getIsAlarmNotify())
                                    {
                                        if (this.axialAlarmRepeatTimes > Page3.getRepeatTimes())
                                        {
                                            if (Page3.getIsAlarmEmail())
                                            {
                                                SendEmail("smtp.qq.com", 587, "24139297@qq.com", "rvsdsfqwexwrbgba", Page3.getAlarmEmail(), "告警通知", "通道：" + channelId + " 轴力值：" + axialForce + " 连续 " + this.axialAlarmRepeatTimes + " 次" + "超过警告阈值：" + Page3.getAxialForceExceeds() + "，请注意！");
                                            }
                                            if (Page3.getIsAlarmPhone())
                                            {
                                                int roundedValue = Convert.ToInt32(axialForce);
                                                string[] templateParamSet = [channelId + "", roundedValue + "", this.axialAlarmRepeatTimes + ""];
                                                SendSms(Page3.getAlarmPhone(), templateParamSet);
                                            }
                                        }
                                    }
                                }

                                if (channelId == this.channelIndex)
                                {
                                    ChartLineRefresh(0, axialForce);
                                }
                            }
                            //保存到Excel文件
                            SaveDataToExcel(values, sensorType);
                            SaveDataToMysql(values, nowTime, sensorType);
                            ShowDataView(columns, channelId);
                        }
                        else
                        {
                            /*
                            string[] values = new string[18];
                            values[0] = channelId + 1 + "";
                            values[1] = rasterCnt / 2 + "";

                            string[] columns = new string[18];
                            columns[0] = channelId + 1 + "";
                            columns[1] = rasterCnt + "";

                            byte[] tempArray = new byte[2 * rasterCnt];
                            Array.Copy(revData, index + 1, tempArray, 0, 2 * rasterCnt);

                            for (byte rasterID = 0; rasterID < rasterCnt; rasterID++)
                            {
                                byte[] tempArray1 = new byte[2];
                                Array.Copy(tempArray, 2 * rasterID, tempArray1, 0, 2);

                                uint valueL = tempArray1[0];
                                uint valueH = tempArray1[1];
                                double waveLength = (double)DivideAndRound((valueL + valueH * 256), 1000, 5) + 1520;

                                values[rasterID + 2] = waveLength + "";
                                columns[rasterID + 2] = waveLength + "";

                                if ((channelId == channelIndex) && (rasterID == rasterIndex))
                                {
                                    ChartLineRefresh(0, waveLength);
                                }
                                //保存到Excel文件
                                SaveDataToExcel(values, sensorType);
                                SaveDataToMysql(values, nowTime, sensorType);
                                ShowDataView(columns, channelId);
                            }
                            */
                        }
                        index = index + 1 + 2 * rasterCnt;
                    }
                    else if (sensorType == 2)//温度传感器
                    {
                        if ((rasterCnt >= 0) && (rasterCnt < rasterCount))
                        {
                            string[] values = new string[34];
                            values[0] = channelId + 1 + "";
                            values[1] = rasterCnt / 2 + "";

                            string[] columns = new string[18];
                            columns[0] = channelId + 1 + "";
                            columns[1] = rasterCnt + "";

                            byte[] tempArray = new byte[2 * rasterCnt];
                            Array.Copy(revData, index + 1, tempArray, 0, 2 * rasterCnt);
                            for (byte rasterID = 0; rasterID < rasterCnt; rasterID++)
                            {
                                byte[] tempArray1 = new byte[2];
                                Array.Copy(tempArray, 2 * rasterID, tempArray1, 0, 2);

                                uint valueL = tempArray1[0];
                                uint valueH = tempArray1[1];
                                double waveLength1 = (double)DivideAndRound((valueL + valueH * 256), 1000, 5) + 1520;

                                //则传感器实时温度：(变量名 – 初始状态波长 )*1000/(转换系数 10pm/℃)+初始温度;
                                double tempValue1 = (waveLength1 - Page3.getTempStartWave()) * 1000 / 10 + Page3.getTempStartValue();

                                values[2 * rasterID + 2] = waveLength1 + "";
                                values[2 * rasterID + 3] = tempValue1 + "";

                                columns[rasterID + 2] = waveLength1 + "";

                                if ((channelId == channelIndex) && (rasterID == rasterIndex))
                                {
                                    ChartLineRefresh(0, tempValue1);
                                }
                            }
                            //保存到Excel文件
                            SaveDataToExcel(values, sensorType);
                            SaveDataToMysql(values, nowTime, sensorType);
                            ShowDataView(columns, channelId);
                        }
                        index = index + 1 + 2 * rasterCnt;
                    }
                    else if (sensorType == 3)//位移传感器
                    {
                        if ((rasterCnt >= 0) && (rasterCnt % 2 == 0) && (rasterCnt < rasterCount))
                        {
                            string[] values = new string[26];
                            values[0] = channelId + 1 + "";
                            values[1] = rasterCnt / 2 + "";

                            string[] columns = new string[18];
                            columns[0] = channelId + 1 + "";
                            columns[1] = rasterCnt + "";

                            byte[] tempArray = new byte[2 * rasterCnt];
                            Array.Copy(revData, index + 1, tempArray, 0, 2 * rasterCnt);

                            for (byte rasterID = 0; rasterID < rasterCnt; rasterID++)
                            {
                                byte[] tempArray1 = new byte[2];
                                Array.Copy(tempArray, 2 * rasterID, tempArray1, 0, 2);

                                uint valueL1 = tempArray1[0];
                                uint valueH1 = tempArray1[1];
                                double waveLength1 = (double)DivideAndRound((valueL1 + valueH1 * 256), 1000, 5) + 1520;

                                byte[] tempArray2 = new byte[2];
                                Array.Copy(tempArray, 2 * (rasterID + 1), tempArray2, 0, 2);

                                uint valueL2 = tempArray2[0];
                                uint valueH2 = tempArray2[1];
                                double waveLength2 = (double)DivideAndRound((valueL2 + valueH2 * 256), 1000, 5) + 1520;

                                //△L=A((λ1-λ2)-(λ10-λ20))²+B((λ1-λ2)-(λ10- λ20))+C
                                double stressValue = CalculateDisplacement(waveLength1, waveLength2, Page3.getMoveStartWave10(), Page3.getMoveStartWave20(), Page3.getA(), Page3.getB(), Page3.getC());

                                values[2] = waveLength1 + "";
                                values[3] = waveLength2 + "";
                                values[4] = stressValue + "";

                                columns[rasterID + 2] = waveLength1 + "";
                                columns[rasterID + 3] = waveLength2 + "";

                                rasterID++;

                                if (channelId == this.channelIndex)
                                {
                                    ChartLineRefresh(0, stressValue);
                                }
                            }
                            //保存到Excel文件
                            SaveDataToExcel(values, sensorType);
                            SaveDataToMysql(values, nowTime, sensorType);
                            ShowDataView(columns, channelId);
                        }
                        index = index + 1 + 2 * rasterCnt;
                    }
                    else//普通传感器
                    {
                        if ((rasterCnt >= 0) && (rasterCnt < rasterCount))
                        {
                            string[] values = new string[18];
                            values[0] = channelId + 1 + "";
                            values[1] = rasterCnt / 2 + "";

                            string[] columns = new string[18];
                            columns[0] = channelId + 1 + "";
                            columns[1] = rasterCnt + "";

                            byte[] tempArray = new byte[2 * rasterCnt];
                            Array.Copy(revData, index + 1, tempArray, 0, 2 * rasterCnt);

                            for (byte rasterID = 0; rasterID < rasterCnt; rasterID++)
                            {
                                byte[] tempArray1 = new byte[2];
                                Array.Copy(tempArray, 2 * rasterID, tempArray1, 0, 2);

                                uint valueL = tempArray1[0];
                                uint valueH = tempArray1[1];
                                double waveLength = (double)DivideAndRound((valueL + valueH * 256), 1000, 5) + 1520;

                                values[rasterID + 2] = waveLength + "";
                                columns[rasterID + 2] = waveLength + "";

                                if ((channelId == channelIndex) && (rasterID == rasterIndex))
                                {
                                    ChartLineRefresh(0, waveLength);
                                }
                            }
                            //保存到Excel文件
                            SaveDataToExcel(values, sensorType);
                            SaveDataToMysql(values, nowTime, sensorType);
                            ShowDataView(columns, channelId);
                        }
                        index = index + 1 + 2 * rasterCnt;
                    }
                }
            }
            else if (cmd == 0x14)
            {

            }
            else if (cmd == 0x16)
            {

            }
            else if (cmd == 0x17)
            {

            }
            else if (cmd == 0x24)
            {

            }
            else if (cmd == 0x26)
            {

            }
            else if (cmd == 0x2E)
            {

            }
            else if (cmd == 0x30)
            {

            }
            else if (cmd == 0x32)
            {

            }
            else if (cmd == 0x34)
            {

            }
            else
            {

            }
        }

        public static decimal DivideAndRound(decimal dividend, decimal divisor, int decimalPlaces)
        {
            if (divisor == 0)
            {
                throw new DivideByZeroException();
            }
            decimal result = dividend / divisor;
            return Math.Round(result, decimalPlaces);
        }
        //应变计算公式：ε＝[（A1’－A1）- ((A2’－A2)/ K2) * K3] /K1
        //其中：A1’为应变光栅当前测量波长，A1为应变光栅安装完成后初始波长
        // A2’为温度光栅当前测量波长，A2为温度光栅安装完成后初始波长
        // K1为应变系数， K2为温度光栅温度系数，K3为应变光栅温度系数
        private static double CalculateStress(double waveValue1, double waveValue2, double A1, double A2, double K1, double K2, double K3)
        {
            double stress = ((waveValue2 - A1) - ((waveValue1 - A2) / K2) * K3) / K1;
            
            return Math.Round(stress, 4);
        }

        //位移计算公式：△L=A((λ1-λ2)-(λ10-λ20))²+B((λ1-λ2)-(λ10- λ20))+C
        // 上式中：A,B,C 为多项式系数
        // △L 为仪器长度变化量，单位 mm
        // λ1、λ2 为当前光栅的波长，单位 nm
        // λ10、λ20 为初始光栅的波长(必须用“计算参数”两光栅波长),单位 nm
        private static double CalculateDisplacement(double λ1, double λ2, double λ10, double λ20, double A, double B, double C)
        {
            double stress = A * Math.Pow(((λ1 - λ2) - (λ10 - λ20)), 2) + B * ((λ1 - λ2) - (λ10 - λ20)) + C;

            return Math.Round(stress, 4);
        }

        private void CreateExcelDataFile()
        {
            if (!this.isSaveWaveLength)
            {
                return;
            }
            // 创建Excel应用程序实例
            //if (excelApp == null)
            //{
            //    MessageBox.Show("无法创建excel对象，请确认excel环境是否正常");
            //    return;
            //}
            this.excelApp = new Excel.Application();
            this.excelApp.Visible = false;
            this.excelApp.UserControl = true;
            this.excelApp.DisplayAlerts = false;

            DateTime dt = DateTime.Now;
            //int hour = dt.Hour;
            //int min = dt.Minute;
            //int hh = hour * 60 + min / 1;
            string date = dt.Year.ToString("D4") + dt.Month.ToString("D2") + dt.Day.ToString("D2");
            string filePath;
            if (this.waveFilePath == "")
            {
                filePath = AppDomain.CurrentDomain.BaseDirectory + this.waveFileName + @"-" + date + @".xlsx";
            }
            else
            {
                filePath = this.waveFilePath + this.waveFileName + @"-" + date + @".xlsx";
            }
            Excel.Workbooks workbooks = this.excelApp.Workbooks;
            try
            {
                if (!File.Exists(filePath))
                {
                    File.Copy(AppDomain.CurrentDomain.BaseDirectory + this.waveFileName + @".xlsx", filePath, true);
                }
                this.workbook = workbooks.Add(filePath); //加载模板
            }
            catch (Exception ex)
            {
                bool isUnlocked = FileUnlocker.UnlockFile(filePath);
                if (isUnlocked)
                {
                    this.workbook = workbooks.Add(filePath); //加载模板
                }
                else
                {
                    MessageBox.Show("存储 Excel 文件时出错,文件可能正被打开！\n" + ex.Message);
                    return;
                }
            }
            this.waveFileNameDate = date;
        }

        private void ReadExcelDataFile()
        {
            // 创建Excel应用程序实例
            this.excelApp = new Excel.Application();
            if (this.excelApp == null)
            {
                MessageBox.Show("无法创建excel对象，请确认excel环境是否正常");
                return;

            }
            this.excelApp.Visible = false;
            this.excelApp.UserControl = true;
            this.excelApp.DisplayAlerts = false;

            DateTime dt = DateTime.Today; // 获取今天的日期
            //DateTime yesterday = dt.AddDays(-1); // 获取前一天的日期

            string date = dt.Year.ToString("D4") + dt.Month.ToString("D2") + dt.Day.ToString("D2");
            string filePath;
            if (this.waveFilePath == "")
            {
                filePath = AppDomain.CurrentDomain.BaseDirectory + this.waveFileName + @"-" + date + @".xlsx";
            }
            else
            {
                filePath = this.waveFilePath + this.waveFileName + @"-" + date + @".xlsx";
            }
            Excel.Workbooks workbooks = this.excelApp.Workbooks;
            try
            {
                if (File.Exists(filePath))
                {
                    this.workbook = workbooks.Add(filePath); //加载模板
                }
                else
                {
                    File.Copy(AppDomain.CurrentDomain.BaseDirectory + this.waveFileName + @".xlsx", filePath, true);
                    this.workbook = workbooks.Add(filePath); //加载模板
                }
            }
            catch (Exception ex)
            {
                bool isUnlocked = FileUnlocker.UnlockFile(filePath);
                if (isUnlocked)
                {
                    this.workbook = workbooks.Add(filePath); //加载模板
                }
                else
                {
                    MessageBox.Show("存储 Excel 文件时出错,文件可能正被打开！\n" + ex.Message);
                    return;
                }
            }
        }
        //数据保存到excel
        public void ShowDataView(string[] data, int channelID)
        {
            ColumnData columnData = dataList[channelID];
            columnData.Time = DateTime.Now.ToString();
            columnData.ChannelNumber = data[0];
            columnData.WaveNumber = data[1];
            columnData.Sensor1 = data[2];
            columnData.Sensor2 = data[3];
            columnData.Sensor3 = data[4];
            columnData.Sensor4 = data[5];
            columnData.Sensor5 = data[6];
            columnData.Sensor6 = data[7];
            columnData.Sensor7 = data[8];
            columnData.Sensor8 = data[9];
            columnData.Sensor9 = data[10];
            columnData.Sensor10 = data[11];
            columnData.Sensor11 = data[12];
            columnData.Sensor12 = data[13];
            columnData.Sensor13 = data[14];
            columnData.Sensor14 = data[15];
            columnData.Sensor15 = data[16];
            columnData.Sensor16 = data[17];

            if (uiDataGridView1.InvokeRequired)
            {
                uiDataGridView1.Invoke(new System.Action(() =>
                {
                    // 在这里安全地修改uiDataGri
                    uiDataGridView1.DataSource = dataList;
                    uiDataGridView1.Refresh();
                }));
            }
            else
            {
                // 直接修改，但通常不推荐，因为即使在当前线程，也应该使用Invoke来保持一致性和避免潜在问题
                uiDataGridView1.DataSource = dataList;
                uiDataGridView1.Refresh();
            }
        }

        //数据保存到excel
        public void SaveDataToExcel(string[] data, int sensorType)
        {
            if (!this.isSaveWaveLength)
            {
                return;
            }
            if (this.excelApp == null)
            {
                MessageBox.Show("无法创建 Excel 对象，请确认 Excel 环境是否正常");
                return;
            }
            if (this.workbook == null)
            {
                MessageBox.Show("无法打开 Workbook 对象，请确认 Excel 文件是否正常");
                return;

            }
            DateTime dt = DateTime.Now;
            int hour = dt.Hour;
            int min = dt.Minute;
            int sec = dt.Second;
            int msec = dt.Millisecond;
            //int hh = hour * 60 + min / 1;
            string date = dt.Year.ToString("D4") + dt.Month.ToString("D2") + dt.Day.ToString("D2");
            string filePath;
            if (this.waveFilePath == "")
            {
                filePath = AppDomain.CurrentDomain.BaseDirectory + this.waveFileName + @"-" + date + @".xlsx";
            }
            else
            {
                filePath = this.waveFilePath + this.waveFileName + @"-" + date + @".xlsx";
            }
            if (!this.waveFileNameDate.Equals(date))
            {
                this.workbook.Close(false);
                this.workbook = null;
                //excelApp.Quit();
                //excelApp = null;
                Excel.Workbooks workbooks = this.excelApp.Workbooks;
                if (!File.Exists(filePath))
                {
                    File.Copy(AppDomain.CurrentDomain.BaseDirectory + this.waveFileName + @".xlsx", filePath, true);
                }
                this.workbook = workbooks.Add(filePath); //加载模板
                this.waveFileNameDate = date;
            }

            Excel.Sheets sheets = workbook.Sheets;
            Excel.Worksheet worksheet;
            if (sensorType == 1)
            {
                worksheet = (Excel.Worksheet)sheets.get_Item(2); //第一个工作薄。
            }
            else
            {
                worksheet = (Excel.Worksheet)sheets.get_Item(1); //第一个工作薄。
            }
            if (worksheet == null)
            {
                MessageBox.Show("无法打开 Worksheet 对象，请确认 Excel 文件是否正常");
                return; //工作薄中没有工作表.
            }
            worksheet.Name = date;

            int columnIndex = 1; // A列的索引是1
            int columnCount = CountColumnValues(worksheet, columnIndex);
            //写入标题
            worksheet.Cells[columnCount + 1, 1] = hour.ToString() + ":" + min.ToString() + ":" + sec.ToString() + ":" + msec.ToString();

            //写入数值
            for (int i = 0; i < data.Length; i++)
            {
                worksheet.Cells[columnCount + 1, i + 2] = data[i];
            }
            worksheet.Columns.EntireColumn.AutoFit();//列宽自适应

            try
            {
                this.workbook.Saved = true;
                this.workbook.SaveAs(filePath);
            }
            catch (Exception ex)
            {
                bool isUnlocked = FileUnlocker.UnlockFile(filePath);
                if (isUnlocked)
                {
                    this.workbook.SaveAs(filePath);
                }
                else
                {
                    MessageBox.Show("存储 Excel 文件时出错,文件可能正被打开！\n" + ex.Message);
                    return;
                }
            }
        }

        private int CountColumnValues(Excel.Worksheet worksheet, int columnIndex)
        {
            int valueCount = 0;
            Excel.Range usedRange = worksheet.UsedRange;

            // 获取列的范围
            Excel.Range columnRange = (Excel.Range)worksheet.Columns[columnIndex];
            int lastRow = columnRange.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;

            // 遍历列中的所有单元格
            for (int row = 1; row <= lastRow; row++)
            {
                Excel.Range cell = (Excel.Range)worksheet.Cells[row, columnIndex];
                if (cell.Value2 != null && !cell.Value2.ToString().Trim().Equals(""))
                {
                    valueCount++;
                }
            }

            System.Runtime.InteropServices.Marshal.ReleaseComObject(columnRange);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(usedRange);

            return valueCount;
        }

        public void SaveDataToMysql(string[] data, long nowTime, int sensorType)
        {
            if (isSaveToMysqlDB)
            {
                if(sensorType == 1)
                {
                    MainForm.db.ExecuteSql(
                        MainForm.db.Insert("strain_sensor")
                        .SetColumn("channel_id", data[0])
                        .SetColumn("raster_count", data[1])
                        .SetColumn("collect_time", DateTime.Now)
                        .SetColumn("wave1_temp", data[2])
                        .SetColumn("wave1_flex", data[3])
                        .SetColumn("flex1_value", data[4])
                        .SetColumn("wave2_temp", data[5])
                        .SetColumn("wave2_flex", data[6])
                        .SetColumn("flex2_value", data[7])
                        .SetColumn("stress_value1", data[8])
                        .SetColumn("axial_value1", data[9])
                        .SetColumn("wave3_temp", data[10])
                        .SetColumn("wave3_flex", data[11])
                        .SetColumn("flex3_value", data[12])
                        .SetColumn("wave4_temp", data[13])
                        .SetColumn("wave4_flex", data[14])
                        .SetColumn("flex4_value", data[15])
                        .SetColumn("stress_value2", data[16])
                        .SetColumn("axial_value2", data[17])
                        .SetColumn("wave5_temp", data[18])
                        .SetColumn("wave5_flex", data[19])
                        .SetColumn("flex5_value", data[20])
                        .SetColumn("wave6_temp", data[21])
                        .SetColumn("wave6_flex", data[22])
                        .SetColumn("flex6_value", data[23])
                        .SetColumn("stress_value3", data[24])
                        .SetColumn("axial_value3", data[25])
                        .SetColumn("wave7_temp", data[26])
                        .SetColumn("wave7_flex", data[27])
                        .SetColumn("flex7_value", data[28])
                        .SetColumn("wave8_temp", data[29])
                        .SetColumn("wave8_flex", data[30])
                        .SetColumn("flex8_value", data[31])
                        .SetColumn("stress_value4", data[32])
                        .SetColumn("axial_value4", data[33])
                        .ToSql());
                }
                else if (sensorType == 2)
                {
                    MainForm.db.ExecuteSql(
                        MainForm.db.Insert("temper_sensor")
                        .SetColumn("channel_id", data[0])
                        .SetColumn("raster_count", data[1])
                        .SetColumn("collect_time", DateTime.Now)
                        .SetColumn("wave_length1", data[2])
                        .SetColumn("temp_value1", data[3])
                        .SetColumn("wave_length2", data[4])
                        .SetColumn("temp_value2", data[5])
                        .SetColumn("wave_length3", data[6])
                        .SetColumn("temp_value3", data[7])
                        .SetColumn("wave_length4", data[8])
                        .SetColumn("temp_value4", data[9])
                        .SetColumn("wave_length5", data[10])
                        .SetColumn("temp_value5", data[11])
                        .SetColumn("wave_length6", data[12])
                        .SetColumn("temp_value6", data[13])
                        .SetColumn("wave_length7", data[14])
                        .SetColumn("temp_value7", data[15])
                        .SetColumn("wave_length8", data[16])
                        .SetColumn("temp_value8", data[17])
                        .SetColumn("wave_length9", data[18])
                        .SetColumn("temp_value9", data[19])
                        .SetColumn("wave_length10", data[20])
                        .SetColumn("temp_value10", data[21])
                        .SetColumn("wave_length11", data[22])
                        .SetColumn("temp_value11", data[23])
                        .SetColumn("wave_length12", data[24])
                        .SetColumn("temp_value12", data[25])
                        .SetColumn("wave_length13", data[26])
                        .SetColumn("temp_value13", data[27])
                        .SetColumn("wave_length14", data[28])
                        .SetColumn("temp_value14", data[29])
                        .SetColumn("wave_length15", data[30])
                        .SetColumn("temp_value15", data[31])
                        .SetColumn("wave_length16", data[32])
                        .SetColumn("temp_value16", data[33])
                        .ToSql());
                }
                else if (sensorType == 3)
                {
                    MainForm.db.ExecuteSql(
                        MainForm.db.Insert("displace_sensor")
                        .SetColumn("channel_id", data[0])
                        .SetColumn("raster_count", data[1])
                        .SetColumn("collect_time", DateTime.Now)
                        .SetColumn("wave_length1", data[2])
                        .SetColumn("wave_length2", data[3])
                        .SetColumn("displace_value1", data[4])
                        .SetColumn("wave_length3", data[5])
                        .SetColumn("wave_length4", data[6])
                        .SetColumn("displace_value2", data[7])
                        .SetColumn("wave_length5", data[8])
                        .SetColumn("wave_length6", data[9])
                        .SetColumn("displace_value3", data[10])
                        .SetColumn("wave_length7", data[11])
                        .SetColumn("wave_length8", data[12])
                        .SetColumn("displace_value4", data[13])
                        .SetColumn("wave_length9", data[14])
                        .SetColumn("wave_length10", data[15])
                        .SetColumn("displace_value5", data[16])
                        .SetColumn("wave_length11", data[17])
                        .SetColumn("wave_length12", data[18])
                        .SetColumn("displace_value6", data[19])
                        .SetColumn("wave_length12", data[20])
                        .SetColumn("wave_length14", data[21])
                        .SetColumn("displace_value7", data[22])
                        .SetColumn("wave_length15", data[23])
                        .SetColumn("wave_length16", data[24])
                        .SetColumn("displace_value8", data[25])
                        .ToSql());
                }
                else
                {
                    MainForm.db.ExecuteSql(
                        MainForm.db.Insert("normal_sensor")
                        .SetColumn("channel_id", data[0])
                        .SetColumn("raster_count", data[1])
                        .SetColumn("collect_time", DateTime.Now)
                        .SetColumn("wave_length1", data[2])
                        .SetColumn("wave_length2", data[3])
                        .SetColumn("wave_length3", data[4])
                        .SetColumn("wave_length4", data[5])
                        .SetColumn("wave_length5", data[6])
                        .SetColumn("wave_length6", data[7])
                        .SetColumn("wave_length7", data[8])
                        .SetColumn("wave_length8", data[9])
                        .SetColumn("wave_length9", data[10])
                        .SetColumn("wave_length10", data[11])
                        .SetColumn("wave_length11", data[12])
                        .SetColumn("wave_length12", data[13])
                        .SetColumn("wave_length13", data[14])
                        .SetColumn("wave_length14", data[15])
                        .SetColumn("wave_length15", data[16])
                        .SetColumn("wave_length16", data[17])
                        .ToSql());
                }

            }
        }

        public static void SendEmail(string host, int port, string fromEmail, string password, string toEmail, string subject, string body)
        {
            try
            {
                // 创建邮件消息
                MailMessage mail = new MailMessage();
                mail.From = new MailAddress(fromEmail);
                mail.To.Add(toEmail);
                mail.Subject = subject;
                mail.Body = body;

                // 设置SMTP客户端
                using (SmtpClient client = new SmtpClient(host, port))
                {
                    client.Credentials = new NetworkCredential(fromEmail, password);
                    client.EnableSsl = true; // 如果SMTP服务器需要安全连接，则启用
                    // 发送邮件
                    client.Send(mail);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            finally
            {

            }
        }

        public static void SendSms(string phoneNumber, string[] templateParamSet)
        {
            try
            {
                // 必要步骤：
                // 实例化一个认证对象，入参需要传入腾讯云账户密钥对 SecretId，SecretKey。
                // 为了保护密钥安全，建议将密钥设置在环境变量中或者配置文件中。
                // 硬编码密钥到代码中有可能随代码泄露而暴露，有安全隐患，并不推荐。
                // 这里采用的是从环境变量读取的方式，需要在环境变量中先设置这两个值。
                // SecretId、SecretKey 查询：https://console.cloud.tencent.com/cam/capi
                Credential cred = new Credential
                {
                    //SecretId = Environment.GetEnvironmentVariable("TENCENTCLOUD_SECRET_ID"),
                    //SecretKey = Environment.GetEnvironmentVariable("TENCENTCLOUD_SECRET_KEY")
                    SecretId = "AKIDaRMzSimmfMqDWfcQ1ShkutiNrAIFzXuA",
                    SecretKey = "CAyc6lCQ2cLypW2OaeowtfJqCOemkXBg"
                };

                /* 非必要步骤:
                 * 实例化一个客户端配置对象，可以指定超时时间等配置 */
                ClientProfile clientProfile = new ClientProfile();
                /* SDK默认用TC3-HMAC-SHA256进行签名
                 * 非必要请不要修改这个字段 */
                clientProfile.SignMethod = ClientProfile.SIGN_TC3SHA256;
                /* 非必要步骤
                 * 实例化一个客户端配置对象，可以指定超时时间等配置 */
                HttpProfile httpProfile = new HttpProfile();
                /* SDK默认使用POST方法。
                 * 如果您一定要使用GET方法，可以在这里设置。GET方法无法处理一些较大的请求 */
                httpProfile.ReqMethod = "POST";
                httpProfile.Timeout = 10; // 请求连接超时时间，单位为秒(默认60秒)
                /* 指定接入地域域名，默认就近地域接入域名为 sms.tencentcloudapi.com ，也支持指定地域域名访问，例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */
                httpProfile.Endpoint = "sms.tencentcloudapi.com";
                // 代理服务器，当您的环境下有代理服务器时设定（无需要直接忽略）
                // httpProfile.WebProxy = Environment.GetEnvironmentVariable("HTTPS_PROXY");

                clientProfile.HttpProfile = httpProfile;
                /* 实例化要请求产品(以sms为例)的client对象
                 * 第二个参数是地域信息，可以直接填写字符串ap-guangzhou，支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
                SmsClient client = new SmsClient(cred, "ap-nanjing", clientProfile);

                /* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
                 * 您可以直接查询SDK源码确定SendSmsRequest有哪些属性可以设置
                 * 属性可能是基本类型，也可能引用了另一个数据结构
                 * 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明 */
                SendSmsRequest req = new SendSmsRequest();

                /* 基本类型的设置:
                 * SDK采用的是指针风格指定参数，即使对于基本类型您也需要用指针来对参数赋值。
                 * SDK提供对基本类型的指针引用封装函数
                 * 帮助链接：
                 * 短信控制台: https://console.cloud.tencent.com/smsv2
                 * 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */
                /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666 */
                // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
                req.SmsSdkAppId = "1400957364";

                /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名 */
                // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
                req.SignName = "屏优多科技";

                /* 模板 ID: 必须填写已审核通过的模板 ID */
                // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
                req.TemplateId = "2342074";

                /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
                req.TemplateParamSet = templateParamSet;

                /* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
                 * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号*/
                req.PhoneNumberSet = new System.String[] { "+86" + phoneNumber };

                /* 用户的 session 内容（无需要可忽略）: 可以携带用户侧 ID 等上下文信息，server 会原样返回 */
                req.SessionContext = "告警";

                /* 短信码号扩展号（无需要可忽略）: 默认未开通，如需开通请联系 [腾讯云短信小助手] */
                req.ExtendCode = "";

                /* 国内短信无需填写该项；国际/港澳台短信已申请独立 SenderId 需要填写该字段，默认使用公共 SenderId，无需填写该字段。注：月度使用量达到指定量级可申请独立 SenderId 使用，详情请联系 [腾讯云短信小助手](https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81)。 */
                req.SenderId = "";

                SendSmsResponse resp = client.SendSmsSync(req);

                // 输出json格式的字符串回包
                Console.WriteLine(AbstractModel.ToJsonString(resp));

                /* 当出现以下错误码时，快速解决方案参考
                 * [FailedOperation.SignatureIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.signatureincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
                 * [FailedOperation.TemplateIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.templateincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
                 * [UnauthorizedOperation.SmsSdkAppIdVerifyFail](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunauthorizedoperation.smssdkappidverifyfail-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
                 * [UnsupportedOperation.ContainDomesticAndInternationalPhoneNumber](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunsupportedoperation.containdomesticandinternationalphonenumber-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
                 * 更多错误，可咨询[腾讯云助手](https://tccc.qcloud.com/web/im/index.html#/chat?webAppId=8fa15978f85cb41f7e2ea36920cb3ae1&title=Sms)
                 */
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            Console.Read();
        }

        public static void PullSmsSendStatus()
        {
            try
            {
                // 必要步骤：
                // 实例化一个认证对象，入参需要传入腾讯云账户密钥对 SecretId，SecretKey。
                // 为了保护密钥安全，建议将密钥设置在环境变量中或者配置文件中。
                // 硬编码密钥到代码中有可能随代码泄露而暴露，有安全隐患，并不推荐。
                // 这里采用的是从环境变量读取的方式，需要在环境变量中先设置这两个值。
                // SecretId、SecretKey 查询：https://console.cloud.tencent.com/cam/capi
                Credential cred = new Credential
                {
                    //SecretId = Environment.GetEnvironmentVariable("TENCENTCLOUD_SECRET_ID"),
                    //SecretKey = Environment.GetEnvironmentVariable("TENCENTCLOUD_SECRET_KEY")
                    SecretId = "AKIDaRMzSimmfMqDWfcQ1ShkutiNrAIFzXuA",
                    SecretKey = "CAyc6lCQ2cLypW2OaeowtfJqCOemkXBg"
                };
                /* 非必要步骤:
                 * 实例化一个客户端配置对象，可以指定超时时间等配置 */
                ClientProfile clientProfile = new ClientProfile();
                /* SDK 默认用 TC3-HMAC-SHA256 进行签名
                 * 非必要请不要修改该字段 */
                clientProfile.SignMethod = ClientProfile.SIGN_TC3SHA256;
                /* 非必要步骤
                 * 实例化一个客户端配置对象，可以指定超时时间等配置 */
                HttpProfile httpProfile = new HttpProfile();
                /* SDK 默认使用 POST 方法
                 * 如需使用 GET 方法，可以在此处设置，但 GET 方法无法处理较大的请求 */
                httpProfile.ReqMethod = "POST";
                httpProfile.Timeout = 30; // 请求连接超时时间，单位为秒(默认60秒)
                /* 指定接入地域域名，默认就近地域接入域名为 sms.tencentcloudapi.com ，也支持指定地域域名访问，例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */
                httpProfile.Endpoint = "sms.tencentcloudapi.com";
                // 代理服务器，当您的环境下有代理服务器时设定
                // httpProfile.WebProxy = Environment.GetEnvironmentVariable("HTTPS_PROXY");
                clientProfile.HttpProfile = httpProfile;
                /* 实例化 SMS 的 client 对象
                 * 第二个参数是地域信息，可以直接填写字符串ap-guangzhou，支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
                SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
                /* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
                 * 您可以直接查询 SDK 源码确定 SendSmsRequest 有哪些属性可以设置
                 * 属性可能是基本类型，也可能引用了另一个数据结构
                 * 推荐使用 IDE 进行开发，可以方便地跳转查阅各个接口和数据结构的文档说明 */
                PullSmsSendStatusRequest req = new PullSmsSendStatusRequest();

                /* 基本类型的设置:
                 * SDK 采用的是指针风格指定参数，即使对于基本类型也需要用指针来对参数赋值
                 * SDK 提供对基本类型的指针引用封装函数
                 * 帮助链接：
                 * 短信控制台：https://console.cloud.tencent.com/smsv2
                 * 腾讯云短信小助手：https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */

                // 设置拉取最大条数，最多100条
                req.Limit = 100;
                /* 短信应用 ID: 在 [短信控制台] 添加应用后生成的实际 SdkAppId，例如1400006666 */
                req.SmsSdkAppId = "1400957364";
                // 通过 client 对象调用 PullSmsSendStatus 方法发起请求，注意请求方法名与请求对象是对应的
                // 返回的 resp 是一个 PullSmsSendStatusResponse 类的实例，与请求对象对应
                PullSmsSendStatusResponse resp = client.PullSmsSendStatusSync(req);
                // 输出 JSON 格式的字符串回包
                Console.WriteLine(AbstractModel.ToJsonString(resp));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            Console.Read();
        }

        private void btnCollectWave_Click(object sender, System.EventArgs e)
        {
            bool isOpenServerPort = MainForm.getOpenServerPort();
            if (!isOpenServerPort)
            {
                MessageBox.Show("请先打开服务端口！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Socket serverSocket = MainForm.getServerSocket();
            if (serverSocket == null){
                return;
            }
            EndPoint endPoint = MainForm.getEndPoint();
            //停用按钮，防止多次点击
            this.btnCollectWave.Enabled = false;
            try
            {
                string msg = this.btnCollectWave.Text;
                if ((!string.IsNullOrEmpty(msg)) && ("开始采集".Equals(msg)))
                {
                    //UI显示
                    this.btnCollectWave.Text = "停止采集";
                    this.btnCollectWave.Enabled = true;
                    this.tbWaveFrequency.Enabled = false;
                    this.tbWaveCollectTimes.Enabled = false;
                    this.cbWaveCollectTimes.Enabled = false;
                    this.tbWaveFilePath.Enabled = false;
                    this.ibOpenFilePath.Enabled = false;
                    this.cbWaveSavePath.Enabled = false;

                    //如果不为空
                    byte[] bmsg = { 0x01, 0x0A, 0x55 };
                    if (bmsg != null)
                    {

                        CreateExcelDataFile();

                        //开启接收消息线程
                        receiveThread1 = new Thread(ReciveMessage);
                        receiveThread1.Start();

                        //发送数据包
                        serverSocket.SendTo(bmsg, endPoint);
                    }
                    else
                    {
                        MessageBox.Show("发送数据格式错误：" + msg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    byte[] bmsg = { 0x01, 0x0A, 0x00 };
                    if (bmsg != null)
                    {
                        //UI显示
                        this.btnCollectWave.Text = "开始采集";
                        this.btnCollectWave.Enabled = true;
                        this.tbWaveFrequency.Enabled = true;
                        this.tbWaveCollectTimes.Enabled = true;
                        this.cbWaveCollectTimes.Enabled = true;
                        this.tbWaveFilePath.Enabled = true;
                        this.ibOpenFilePath.Enabled = true;
                        this.cbWaveSavePath.Enabled = true;

                        //发送数据包
                        serverSocket.SendTo(bmsg, endPoint);

                        //先关闭线程，再关闭服务器
                        if (receiveThread1 != null){
                            receiveThread1.Interrupt();
                        }

                        if (this.isSaveWaveLength)
                        {
                            if (this.excelApp != null)
                            {
                                this.excelApp.DisplayAlerts = false;
                                if (this.workbook != null)
                                {
                                    this.workbook.Close(false);
                                    this.workbook = null;
                                }
                                this.excelApp.Quit();
                                this.excelApp = null;
                            }
                        }
                    }
                    else
                    {
                        MessageBox.Show("发送数据格式错误：" + msg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (SocketException es)
            {
                MessageBox.Show("发送数据报时出现异常：" + es.ErrorCode + "！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                //按钮启用
                btnCollectWave.Enabled = true;
            }
        }

        private void cbWaveSensorType_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.sensorType = cbWaveSensorType.SelectedIndex;
            // 假设你在非UI线程上
            if (this.cbWaveSensorType.InvokeRequired)
            {
                this.cbWaveSensorType.Invoke(new System.Action(() =>
                {
                    if (this.sensorType != this.cbWaveSensorType.SelectedIndex)
                    {
                        if (this.cbWaveSensorType.SelectedIndex == 0)
                        {
                            // 假设你在非UI线程上
                            if (OscChart.InvokeRequired)
                            {
                                OscChart.Invoke(new System.Action(() =>
                                {
                                    OscChart.Series.Remove(OscChart.Series[0]);
                                    OscChart.AxisX.Remove(OscChart.AxisX[0]);
                                    OscChart.AxisY.Remove(OscChart.AxisY[0]);
                                    /*
                                    if (this.sensorType == 1)
                                    {
                                        OscChart.Series.Remove(OscChart.Series[1]);
                                        OscChart.AxisX.Remove(OscChart.AxisX[1]);
                                        OscChart.AxisY.Remove(OscChart.AxisY[1]);
                                        OscChart.Series.Remove(OscChart.Series[2]);
                                        OscChart.AxisX.Remove(OscChart.AxisX[2]);
                                        OscChart.AxisY.Remove(OscChart.AxisY[2]);
                                        OscChart.Series.Remove(OscChart.Series[3]);
                                        OscChart.AxisX.Remove(OscChart.AxisX[3]);
                                        OscChart.AxisY.Remove(OscChart.AxisY[3]);
                                        OscChart.Series.Remove(OscChart.Series[4]);
                                        OscChart.AxisX.Remove(OscChart.AxisX[4]);
                                        OscChart.AxisY.Remove(OscChart.AxisY[4]);
                                    }
                                    */
                                }));
                            }
                            else
                            {
                                OscChart.Series.Remove(OscChart.Series[0]);
                                OscChart.AxisX.Remove(OscChart.AxisX[0]);
                                OscChart.AxisY.Remove(OscChart.AxisY[0]);
                                /*
                                if (this.sensorType == 1)
                                {
                                    OscChart.Series.Remove(OscChart.Series[1]);
                                    OscChart.AxisX.Remove(OscChart.AxisX[1]);
                                    OscChart.AxisY.Remove(OscChart.AxisY[1]);
                                    OscChart.Series.Remove(OscChart.Series[2]);
                                    OscChart.AxisX.Remove(OscChart.AxisX[2]);
                                    OscChart.AxisY.Remove(OscChart.AxisY[2]);
                                    OscChart.Series.Remove(OscChart.Series[3]);
                                    OscChart.AxisX.Remove(OscChart.AxisX[3]);
                                    OscChart.AxisY.Remove(OscChart.AxisY[3]);
                                    OscChart.Series.Remove(OscChart.Series[4]);
                                    OscChart.AxisX.Remove(OscChart.AxisX[4]);
                                    OscChart.AxisY.Remove(OscChart.AxisY[4]);
                                }
                                */
                            }
                            InitChartConfig();
                        }
                        else if (this.cbWaveSensorType.SelectedIndex == 1)
                        {
                            // 假设你在非UI线程上
                            if (OscChart.InvokeRequired)
                            {
                                OscChart.Invoke(new System.Action(() =>
                                {
                                    OscChart.Series.Remove(OscChart.Series[0]);
                                    OscChart.AxisX.Remove(OscChart.AxisX[0]);
                                    OscChart.AxisY.Remove(OscChart.AxisY[0]);
                                }));
                            }
                            else
                            {
                                OscChart.Series.Remove(OscChart.Series[0]);
                                OscChart.AxisX.Remove(OscChart.AxisX[0]);
                                OscChart.AxisY.Remove(OscChart.AxisY[0]);
                            }
                            InitChartConfig(channelIndex, 0, 0);
                            /*
                            if (this.sensorType == 1)
                            {
                                InitChartConfig(channelIndex, 1, 1);
                                InitChartConfig(channelIndex, 2, 2);
                                InitChartConfig(channelIndex, 3, 3);
                                InitChartConfig(channelIndex, 4, 4);
                            }
                            */
                        }
                        this.sensorType = this.cbWaveSensorType.SelectedIndex;
                    }
                }));
            }
            else
            {
                // 直接进行操作，因为当前线程就是UI线程
                if (this.sensorType != this.cbWaveSensorType.SelectedIndex)
                {
                    if (this.cbWaveSensorType.SelectedIndex == 0)
                    {
                        // 假设你在非UI线程上
                        if (OscChart.InvokeRequired)
                        {
                            OscChart.Invoke(new System.Action(() =>
                            {
                                OscChart.Series.Remove(OscChart.Series[0]);
                                OscChart.AxisX.Remove(OscChart.AxisX[0]);
                                OscChart.AxisY.Remove(OscChart.AxisY[0]);
                            }));
                        }
                        else
                        {
                            OscChart.Series.Remove(OscChart.Series[0]);
                            OscChart.AxisX.Remove(OscChart.AxisX[0]);
                            OscChart.AxisY.Remove(OscChart.AxisY[0]);
                        }
                        /*
                        if (this.sensorType == 1)
                        {
                            OscChart.Series.Remove(OscChart.Series[1]);
                            OscChart.AxisX.Remove(OscChart.AxisX[1]);
                            OscChart.AxisY.Remove(OscChart.AxisY[1]);
                            OscChart.Series.Remove(OscChart.Series[2]);
                            OscChart.AxisX.Remove(OscChart.AxisX[2]);
                            OscChart.AxisY.Remove(OscChart.AxisY[2]);
                            OscChart.Series.Remove(OscChart.Series[3]);
                            OscChart.AxisX.Remove(OscChart.AxisX[3]);
                            OscChart.AxisY.Remove(OscChart.AxisY[3]);
                            OscChart.Series.Remove(OscChart.Series[4]);
                            OscChart.AxisX.Remove(OscChart.AxisX[4]);
                            OscChart.AxisY.Remove(OscChart.AxisY[4]);
                        }
                        */
                        InitChartConfig();
                    }
                    else if (this.cbWaveSensorType.SelectedIndex == 1)
                    {
                        // 假设你在非UI线程上
                        if (OscChart.InvokeRequired)
                        {
                            OscChart.Invoke(new System.Action(() =>
                            {
                                OscChart.Series.Remove(OscChart.Series[0]);
                                OscChart.AxisX.Remove(OscChart.AxisX[0]);
                                OscChart.AxisY.Remove(OscChart.AxisY[0]);
                            }));
                        }
                        else
                        {
                            OscChart.Series.Remove(OscChart.Series[0]);
                            OscChart.AxisX.Remove(OscChart.AxisX[0]);
                            OscChart.AxisY.Remove(OscChart.AxisY[0]);
                        }
                        InitChartConfig(channelIndex, 0, 0);
                        /*
                        InitChartConfig(channelIndex, 1, 1);
                        InitChartConfig(channelIndex, 2, 2);
                        InitChartConfig(channelIndex, 3, 3);
                        InitChartConfig(channelIndex, 4, 4);
                        */
                    }
                    this.sensorType = this.cbWaveSensorType.SelectedIndex;
                }
            }
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            AppSettingsSection app = config.AppSettings;
            app.Settings["cbWaveSensorType"].Value = this.cbWaveSensorType.SelectedIndex + "";
            config.Save(ConfigurationSaveMode.Modified);
        }
        private void cbWaveChannelSellect_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 假设你在非UI线程上
            if (this.cbWaveChannelSellect.InvokeRequired)
            {
                this.cbWaveChannelSellect.Invoke(new System.Action(() =>
                {
                    if (this.channelIndex != this.cbWaveChannelSellect.SelectedIndex)
                    {
                        this.channelIndex = this.cbWaveChannelSellect.SelectedIndex;
                        // 假设你在非UI线程上
                        if (OscChart.InvokeRequired)
                        {
                            OscChart.Invoke(new System.Action(() =>
                            {
                                OscChart.Series.Remove(OscChart.Series[0]);
                                OscChart.AxisX.Remove(OscChart.AxisX[0]);
                                OscChart.AxisY.Remove(OscChart.AxisY[0]);
                            }));
                        }
                        else
                        {
                            OscChart.Series.Remove(OscChart.Series[0]);
                            OscChart.AxisX.Remove(OscChart.AxisX[0]);
                            OscChart.AxisY.Remove(OscChart.AxisY[0]);
                        }
                        InitChartConfig();
                    }
                }));
            }
            else
            {
                // 直接进行操作，因为当前线程就是UI线程
                if (this.channelIndex != this.cbWaveChannelSellect.SelectedIndex)
                {
                    this.channelIndex = this.cbWaveChannelSellect.SelectedIndex;
                    // 假设你在非UI线程上
                    if (OscChart.InvokeRequired)
                    {
                        OscChart.Invoke(new System.Action(() =>
                        {
                            OscChart.Series.Remove(OscChart.Series[0]);
                            OscChart.AxisX.Remove(OscChart.AxisX[0]);
                            OscChart.AxisY.Remove(OscChart.AxisY[0]);
                        }));
                    }
                    else
                    {
                        OscChart.Series.Remove(OscChart.Series[0]);
                        OscChart.AxisX.Remove(OscChart.AxisX[0]);
                        OscChart.AxisY.Remove(OscChart.AxisY[0]);
                    }
                    InitChartConfig();
                }
            }
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            AppSettingsSection app = config.AppSettings;
            app.Settings["cbWaveChannelSellect"].Value = this.cbWaveChannelSellect.Text;
            config.Save(ConfigurationSaveMode.Modified);
        }

        private void cbWaveSensorSellect_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 假设你在非UI线程上
            if (this.cbWaveSensorSellect.InvokeRequired)
            {
                this.cbWaveSensorSellect.Invoke(new System.Action(() =>
                {
                    if (this.rasterIndex != this.cbWaveSensorSellect.SelectedIndex)
                    {
                        this.rasterIndex = this.cbWaveSensorSellect.SelectedIndex;
                        if (OscChart.InvokeRequired)
                        {
                            OscChart.Invoke(new System.Action(() =>
                            {
                                OscChart.Series.Remove(OscChart.Series[0]);
                                OscChart.AxisX.Remove(OscChart.AxisX[0]);
                                OscChart.AxisY.Remove(OscChart.AxisY[0]);
                            }));
                        }
                        else
                        {
                            OscChart.Series.Remove(OscChart.Series[0]);
                            OscChart.AxisX.Remove(OscChart.AxisX[0]);
                            OscChart.AxisY.Remove(OscChart.AxisY[0]);
                        }
                        InitChartConfig();
                    }
                }));
            }
            else
            {
                // 直接进行操作，因为当前线程就是UI线程
                if (this.rasterIndex != this.cbWaveSensorSellect.SelectedIndex)
                {
                    this.rasterIndex = this.cbWaveSensorSellect.SelectedIndex;
                    if (OscChart.InvokeRequired)
                    {
                        OscChart.Invoke(new System.Action(() =>
                        {
                            OscChart.Series.Remove(OscChart.Series[0]);
                            OscChart.AxisX.Remove(OscChart.AxisX[0]);
                            OscChart.AxisY.Remove(OscChart.AxisY[0]);
                        }));
                    }
                    else
                    {
                        OscChart.Series.Remove(OscChart.Series[0]);
                        OscChart.AxisX.Remove(OscChart.AxisX[0]);
                        OscChart.AxisY.Remove(OscChart.AxisY[0]);
                    }
                    InitChartConfig();
                }
            }
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            AppSettingsSection app = config.AppSettings;
            app.Settings["cbWaveSensorSellect"].Value = this.cbWaveSensorSellect.Text;
            config.Save(ConfigurationSaveMode.Modified);

        }

        private void tbWaveFrequency_TextChanged(object sender, EventArgs e)
        {
            if (this.tbWaveFrequency.Text.Length > 0)
            {
                long _frequency = Convert.ToInt64(this.tbWaveFrequency.Text);
                //转换成长整型
                if (this.frequency != _frequency)
                {
                    this.frequency = _frequency;
                    this.intervalTime = 1000 / this.frequency;
                    this.xCount = this.showTimes * this.frequency;
                }
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                AppSettingsSection app = config.AppSettings;
                app.Settings["tbWaveFrequency"].Value = this.tbWaveFrequency.Text;
                config.Save(ConfigurationSaveMode.Modified);
            }
        }

        private void cbWaveSavePath_CheckedChanged(object sender, EventArgs e)
        {
            this.isSaveWaveLength = this.cbWaveSavePath.Checked;
            this.tbWaveFilePath.Enabled = this.cbWaveSavePath.Checked;
            this.ibOpenFilePath.Enabled = this.cbWaveSavePath.Checked;

            //if (this.isSaveWaveLength)
            //{
            //    CreateExcelDataFile(this.waveFilePath);
            //}
            //else
            //{
            //    if (excelApp != null)
            //    {
            //        excelApp.DisplayAlerts = false;
            //        if (workbook != null)
            //        {
            //            workbook.Close(false);
            //            workbook = null;
            //        }
            //        excelApp.Quit();
            //        excelApp = null;
            //    }
            //}
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            AppSettingsSection app = config.AppSettings;
            app.Settings["cbWaveSavePath"].Value = this.cbWaveSavePath.Checked.ToString();
            config.Save(ConfigurationSaveMode.Modified);
        }

        private void tbWaveFilePath_TextChanged(object sender, EventArgs e)
        {
            if (this.tbWaveFilePath.Text.Length > 0)
            {
                if (!this.waveFilePath.Equals(this.tbWaveFilePath.Text))
                {
                    this.waveFilePath = this.tbWaveFilePath.Text;
                    if (this.isSaveWaveLength)
                    {
                        if (this.excelApp != null)
                        {
                            this.excelApp.DisplayAlerts = false;
                            if (this.workbook != null)
                            {
                                this.workbook.Close(false);
                                this.workbook = null;
                            }
                            this.excelApp.Quit();
                            this.excelApp = null;
                        }
                        CreateExcelDataFile();
                    }
                    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                    AppSettingsSection app = config.AppSettings;
                    app.Settings["tbWaveFilePath"].Value = this.tbWaveFilePath.Text;
                    config.Save(ConfigurationSaveMode.Modified);
                }
            }
        }

        private void cbWaveCollectTimes_CheckedChanged(object sender, EventArgs e)
        {
            this.tbWaveCollectTimes.Enabled = this.cbWaveCollectTimes.Checked;
            this.isWaveCollectTimes = this.cbWaveCollectTimes.Checked;
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            AppSettingsSection app = config.AppSettings;
            app.Settings["cbWaveCollectTimes"].Value = this.cbWaveCollectTimes.Checked.ToString();
            config.Save(ConfigurationSaveMode.Modified);
        }

        private void tbWaveCollectTimes_TextChanged(object sender, EventArgs e)
        {
            if (this.tbWaveCollectTimes.Text.Length > 0)
            {
                this.waveCollectTimes = Convert.ToInt32(this.tbWaveCollectTimes.Text);
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                AppSettingsSection app = config.AppSettings;
                app.Settings["tbWaveCollectTimes"].Value = this.tbWaveCollectTimes.Text;
                config.Save(ConfigurationSaveMode.Modified);
            }
        }

        private void ibOpenFilePath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            folderBrowserDialog.ShowDialog();
            this.tbWaveFilePath.Text = folderBrowserDialog.SelectedPath; //获得选择的文件夹路径
        }

        private void cbSimulationTest_CheckedChanged(object sender, EventArgs e)
        {
            this.debug = this.cbSimulationTest.Checked;
        }
    }


}